package com.insight.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.insight.common.constant.CacheConstant;
import com.insight.common.constant.CommonConstant;
import com.insight.common.exception.JeecgBootException;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.SysPermission;
import com.insight.modules.system.entity.SysPermissionDataRule;
import com.insight.modules.system.mapper.SysDepartPermissionMapper;
import com.insight.modules.system.mapper.SysDepartRolePermissionMapper;
import com.insight.modules.system.mapper.SysPermissionMapper;
import com.insight.modules.system.mapper.SysRolePermissionMapper;
import com.insight.modules.system.model.TreeModel;
import com.insight.modules.system.service.ISysPermissionDataRuleService;
import com.insight.modules.system.service.ISysPermissionService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @Author scott
 * @since 2018-12-21
 */
/**
 * 系统菜单权限服务实现类
 * 负责处理菜单的增删改查及权限规则等相关业务逻辑
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService {

	// 菜单权限持久层接口，用于执行菜单相关的数据库操作
	@Resource
	private SysPermissionMapper sysPermissionMapper;
	// 权限数据规则服务，处理菜单数据权限规则相关逻辑
	@Resource
	private ISysPermissionDataRuleService permissionDataRuleService;
	// 角色权限映射表的持久层接口，用于角色和菜单权限之间的绑定管理
	@Resource
	private SysRolePermissionMapper sysRolePermissionMapper;
	// 部门权限映射表的持久层接口，用于部门和菜单权限之间的绑定管理
	@Resource
	private SysDepartPermissionMapper sysDepartPermissionMapper;
	// 部门角色权限映射表的持久层接口，用于部门角色和菜单权限之间的绑定管理
	@Resource
	private SysDepartRolePermissionMapper sysDepartRolePermissionMapper;

	/**
	 * 查询所有菜单（不分页）
	 * @return 所有菜单列表（不含按钮权限）
	 */
	@Override
	public List<SysPermission> queryList() {
		LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
		query.orderByAsc(SysPermission::getSortNo);
		return this.list(query);
	}

	/**
	 * 根据菜单ID删除菜单，并处理其子级菜单的级联删除，同时清理权限绑定关系
	 * @param id 菜单ID
	 */
	@Override
	@Transactional
	public void removePermission(String id) {
		SysPermission sysPermission = this.getById(id);
		if (sysPermission != null) {
			// 递归删除所有子菜单
			removeChildrenBy(sysPermission.getId());
			// 删除当前菜单
			this.removeById(sysPermission.getId());

			// 清除角色权限绑定
			sysRolePermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysRolePermission>().eq(SysRolePermission::getPermissionId, id));
			// 清除部门权限绑定
			sysDepartPermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysDepartPermission>().eq(SysDepartPermission::getPermissionId, id));
			// 清除部门角色权限绑定
			sysDepartRolePermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysDepartRolePermission>().eq(SysDepartRolePermission::getPermissionId, id));
		}
	}

	/**
	 * 递归删除子菜单（逻辑删除）
	 * @param parentId 父级菜单ID
	 */
	private void removeChildrenBy(String parentId) {
		List<SysPermission> children = this.list(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getParentId, parentId));
		for (SysPermission child : children) {
			removeChildrenBy(child.getId()); // 递归删除
			this.removeById(child.getId());
			// 同时清理相关绑定
			sysRolePermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysRolePermission>().eq(SysRolePermission::getPermissionId, child.getId()));
			sysDepartPermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysDepartPermission>().eq(SysDepartPermission::getPermissionId, child.getId()));
			sysDepartRolePermissionMapper.delete(new LambdaQueryWrapper<com.insight.modules.system.entity.SysDepartRolePermission>().eq(SysDepartRolePermission::getPermissionId, child.getId()));
		}
	}

	/**
	 * 查询指定用户的菜单权限（含按钮）
	 * @param username 用户名
	 * @return 用户可访问的菜单权限列表
	 */
	@Override
	public List<SysPermission> queryByUser(String username) {
		return baseMapper.queryByUser(username);
	}

	/**
	 * 根据菜单ID获取其绑定的数据权限规则
	 * @param permissionId 菜单ID
	 * @return 权限数据规则列表
	 */
	@Override
	public List<SysPermissionDataRule> getPermRuleListByPermId(String permissionId) {
		return permissionDataRuleService.getPermRuleListByPermId(permissionId);
	}

	/**
	 * 校验菜单名称是否唯一
	 * @param name 菜单名称
	 * @param parentId 上级菜单ID
	 * @param id 当前菜单ID（编辑场景忽略自己）
	 * @return true 表示名称唯一；false 表示已存在
	 */
	@Override
	public boolean isNameUnique(String name, String parentId, String id) {
		LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
		query.eq(SysPermission::getName, name).eq(SysPermission::getParentId, parentId);
		if (StringUtils.isNotBlank(id)) {
			query.ne(SysPermission::getId, id);
		}
		return this.count(query) == 0;
	}

	/**
	 * 更新菜单规则标识（ruleFlag 字段）
	 * @param permissionId 菜单ID
	 * @param ruleFlag 是否有数据权限规则（1 有，0 无）
	 */
	@Override
	public void updateRuleFlag(String permissionId, Integer ruleFlag) {
		SysPermission permission = new SysPermission();
		permission.setId(permissionId);
		permission.setRuleFlag(ruleFlag);
		this.updateById(permission);
	}
}

